package com.glodon.jcloud.increment.shorturl.config;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.glodon.jcloud.increment.common.enums.CommonDeleteFlagEnum;
import com.glodon.jcloud.increment.shorturl.filter.BasicAuthFilter;
import com.glodon.jcloud.increment.shorturl.service.OAuth2ClientService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectionException;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Date;

/**
 * <p>
 * Create Date: 2022/12/6
 *
 * @version: V0.0.1-SNAPSHOT
 * @author: Terry.Li
 * @mail: lib-o@glodon.com
 */
@Slf4j
@Configuration
@MapperScan(basePackages = {"com.glodon.jcloud.increment.shorturl.mapper"})
public class SystemConfigure implements WebMvcConfigurer {

    @Resource
    private OAuth2ClientService oAuth2ClientService;

    @Bean
    public FilterRegistrationBean<BasicAuthFilter> basicAuthFilter() {
        FilterRegistrationBean<BasicAuthFilter> registration = new FilterRegistrationBean<>();
        registration.setName("basicAuthFilter");
        registration.setFilter(new BasicAuthFilter(oAuth2ClientService));
        registration.addUrlPatterns("/*");
        registration.addInitParameter("excludeUrl", "/api/oauth2/authentication,/api/oauth2/authorize,/api/oauth2/access_token,/doc.html");
        registration.setOrder(1);
        return registration;
    }

    /**
     * Mybatis plus interceptor mybatis plus interceptor.
     *
     * @return the mybatis plus interceptor
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }

    /**
     * The type Custom db id provider.
     */
    @Component
    public static class CustomDbIdProvider implements DatabaseIdProvider {

        @Override
        public String getDatabaseId(DataSource dataSource) throws SQLException {
            String url = dataSource.getConnection().getMetaData().getURL();
            if (url.contains("oracle")) {
                return "oracle";
            } else if (url.contains("postgresql")) {
                return "pgsql";
            } else if (url.contains("mysql")) {
                return "mysql";
            } else if (url.contains("dm")) {
                return "dm";
            } else if (url.contains("kingbase")) {
                return "kingbase";
            } else {
                return "mysql";
            }
        }
    }

    /**
     * The type Custom meta object handler.
     */
    @Component
    public static class CustomMetaObjectHandler implements MetaObjectHandler {

        /**
         * 删除标志
         */
        private static final String DELETE_FLAG = "deleteFlag";

        /**
         * 创建人
         */
        private static final String CREATE_USER = "creator";

        /**
         * 创建时间
         */
        private static final String CREATE_TIME = "createdate";

        /**
         * 更新人
         */
        private static final String UPDATE_USER = "modifier";

        /**
         * 更新时间
         */
        private static final String UPDATE_TIME = "modifydate";

        @Override
        public void insertFill(MetaObject metaObject) {
            try {
                //为空则设置deleteFlag
                Object deleteFlag = metaObject.getValue(DELETE_FLAG);
                if (ObjectUtil.isNull(deleteFlag)) {
                    setFieldValByName(DELETE_FLAG, EnumUtil.toString(CommonDeleteFlagEnum.NOT_DELETE), metaObject);
                }
            } catch (ReflectionException ignored) {
            }
            try {
                //为空则设置createTime
                Object createTime = metaObject.getValue(CREATE_TIME);
                if (ObjectUtil.isNull(createTime)) {
                    setFieldValByName(CREATE_TIME, new Date(), metaObject);
                }
            } catch (ReflectionException ignored) {
            }
        }

        @Override
        public void updateFill(MetaObject metaObject) {
            try {
                //设置updateTime
                setFieldValByName(UPDATE_TIME, DateTime.now(), metaObject);
            } catch (ReflectionException ignored) {
            }
        }
    }
}
